/* 
 *	Copyright (C) 2009-2010 miaohua
 *	http://code.google.com/p/lrcshower/
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */
#include "StdAfx.h"
#include <Windows.h>
#include <string>
#include "TypeDef.h"
#include "ConstDef.h"
#include "SearchEngineComHdr.h"
#include "BaiduMusic.h"
#include "SogouMusic.h"
#include "HelperFunctions.h"
#include "LrcSearchSetting.h"
#include "RegOptHelper.h"
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern const TCHAR * LocalFolder[UserFolder+1]=
{
     _T("DownloadLrcFolder"),
     _T("SongFolder"),
     _T("UserSetFolder")
};

LrcSearchSetting::LrcSearchSetting(const tstring & RegPath)
{
     // Get register path
     m_RegPath = RegPath;
     // Load value from register 
     if( !DeserializeFromReg() )
         SetDefaultVal();
     // Initialize the search engine api array
     EngineAPI BaiduApi, SogouApi;

     BaiduApi.GetEngineName = BaiduGetEngineName;
     BaiduApi.SearchSong = BaiduSearchSong;
     BaiduApi.SearchLrc = BaiduSearchLrc;
     BaiduApi.GetMp3DownloadUrl = BaiduGetMp3DownloadUrl;
     BaiduApi.GetLrcDownloadUrl = BaiduGetLrcDownloadUrl;
     BaiduApi.GetSongTotalNum = BaiduGetSongTotalNum;
     BaiduApi.GetLrcTotalNum = BaiduGetLrcTotalNum;
     BaiduApi.GetEngineLogo = BaiduGetEngineLogo;

     SogouApi.GetEngineName = SogouGetEngineName;
     SogouApi.SearchSong = SogouSearchSong;
     SogouApi.SearchLrc = SogouSearchLrc;
     SogouApi.GetMp3DownloadUrl = SogouGetMp3DownloadUrl;
     SogouApi.GetLrcDownloadUrl = SogouGetLrcDownloadUrl;
     SogouApi.GetSongTotalNum = SogouGetSongTotalNum;
     SogouApi.GetLrcTotalNum = SogouGetLrcTotalNum;
     SogouApi.GetEngineLogo = SogouGetEngineLogo;

     m_SearchEngineAPI.push_back(SogouApi);
     m_SearchEngineAPI.push_back(BaiduApi);
}

LrcSearchSetting::~LrcSearchSetting()
{
     SerializeToReg();
}

bool LrcSearchSetting::SerializeToReg()
{
     // Reg location
     const TCHAR * Path = m_RegPath.c_str();
     // Open the reg key
     DWORD Disp = REG_OPENED_EXISTING_KEY;
     HKEY FilterKey;
     if( RegCreateKeyEx(HKEY_LOCAL_MACHINE, Path, 0, NULL, REG_OPTION_NON_VOLATILE,
         KEY_WRITE, NULL, &FilterKey, &Disp) !=ERROR_SUCCESS )
	     return false;

     // Put key to realse helper
     RegKeyReleaseHelper AutoReleaseKey(FilterKey);

     // Save auto search value
     DWORD ModeBool = m_AutoSearch;
     if( RegSetValueEx(FilterKey, _T("AutoSearch") ,NULL, REG_DWORD, (const BYTE*)&ModeBool, sizeof(DWORD)) != ERROR_SUCCESS )
         return false;

     // Save select randomly value
     ModeBool = m_SelRandom;
     if( RegSetValueEx(FilterKey, _T("SelRandom") ,NULL, REG_DWORD, (const BYTE*)&ModeBool, sizeof(DWORD)) != ERROR_SUCCESS )
         return false;

     // Save propmt to user if there are multi lrc files
     ModeBool = m_PromptMulti;
     if( RegSetValueEx(FilterKey, _T("PropmtMulti") ,NULL, REG_DWORD, (const BYTE*)&ModeBool, sizeof(DWORD)) !=ERROR_SUCCESS )
         return false;
     
     // Save the value of auto parser
     ModeBool = m_AutoParse;
     if( RegSetValueEx(FilterKey, _T("AutoParser") ,NULL, REG_DWORD, (const BYTE*)&ModeBool, sizeof(DWORD)) !=ERROR_SUCCESS )
         return false;

     // Save the value of lrc search eingine index 
     DWORD Val = m_SearchEngineIdx;
     if( RegSetValueEx(FilterKey, _T("SearchEngineIdx") ,NULL, REG_DWORD, (const BYTE*)&Val, sizeof(DWORD)) !=ERROR_SUCCESS )
         return false;
     
     // Save folder path
     SaveRegSZVal(FilterKey, _T("FloderPath"), m_FolderPath);

     // Save folder list for local search
     Val = m_FolderList.size();
     if( RegSetValueEx(FilterKey, _T("LocalSearchFolderNum") ,NULL, REG_DWORD, (const BYTE*)&Val, sizeof(DWORD)) !=ERROR_SUCCESS )
         return false;
     for( unsigned int i = 0; i < Val; ++i )
     {
          tstring KeyName = _T("LocalSearchFolderType") + IntToStr(i);
          SaveRegSZVal(FilterKey, KeyName, m_FolderList[i].first);
          KeyName = _T("LocalSearchFolder") + IntToStr(i);
          SaveRegSZVal(FilterKey, KeyName, m_FolderList[i].second);
     }

     // Save reg key values
     RegFlushKey(FilterKey);

     return true; 
}

bool LrcSearchSetting::DeserializeFromReg()
{ 
     // Reg location
     const TCHAR * Path = m_RegPath.c_str();
     // Open the reg key
     HKEY FilterKey;
     if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, Path, 0, KEY_READ, &FilterKey) !=ERROR_SUCCESS )
	     return false;

     // Put key to realse helper
     RegKeyReleaseHelper AutoReleaseKey(FilterKey);

     // Get auto search value
     QueryRegBoolVal(FilterKey, _T("AutoSearch"), m_AutoSearch, return false);

     // Get select randomly value
     QueryRegBoolVal(FilterKey, _T("SelRandom"), m_SelRandom, return false);

     // Get propmt to user if there are multi lrc files
     QueryRegBoolVal(FilterKey, _T("PropmtMulti"), m_PromptMulti, return false);

     // Get auto parse value
     QueryRegBoolVal(FilterKey, _T("AutoParser"), m_AutoParse, return false);

     // Save the value of lrc search eingine index
     QueryRegDWORDVal(FilterKey, _T("SearchEngineIdx"), m_SearchEngineIdx, return false);

     // Get lrc files saving folder
     QueryRegSZVal(FilterKey, _T("FloderPath"), m_FolderPath);

     // Get local search folder list
     DWORD FolderNum = 0;
     QueryRegDWORDVal(FilterKey, _T("LocalSearchFolderNum"), FolderNum, return false);

     m_FolderList.clear();
     m_FolderList.reserve(FolderNum);

     for( unsigned int i = 0; i < FolderNum; ++i )
     {
          tstring Type, Folder;
          tstring KeyName = _T("LocalSearchFolderType") + IntToStr(i);
          QueryRegSZVal(FilterKey, KeyName, Type);
          KeyName = _T("LocalSearchFolder") + IntToStr(i);
          QueryRegSZVal(FilterKey, KeyName, Folder);
          m_FolderList.push_back(make_pair(Type, Folder));
     } 

     return true; 
}

bool LrcSearchSetting::SerializeToXML(){ return true; }
bool LrcSearchSetting::DeserializeFromXML(){ return true; }
void LrcSearchSetting::SetDefaultVal()
{
     m_SearchEngineIdx = 0;   // Default search engine is sogou
     m_AutoSearch = true;
     m_SelRandom = false;
     m_PromptMulti = true;
     m_AutoParse = true;

     // Default local lrc search folders
     m_FolderList.push_back(make_pair(LocalFolder[LrcFolder], Def_LrcSearch_LrcFolder));
     m_FolderList.push_back(make_pair(LocalFolder[SongFolder], Def_LrcSearch_SongFolder));
     // Default download lrc files' saving folder
     // <<app's folder>>\Lyrics
     TCHAR AppFolder[MAX_PATH+1];
     GetModuleFileName(NULL, AppFolder, MAX_PATH);
     (_tcsrchr(AppFolder, _T('\\')))[1] = 0;
     m_FolderPath = AppFolder;
     m_FolderPath = m_FolderPath + Def_Lrc_Folder;
     _tmkdir(m_FolderPath.c_str());

}

bool LrcSearchSetting::CheckDefaulFolder(int Index)
{
     if( Index >= 0 && Index < m_FolderList.size() )
         return ( m_FolderList[Index].first == LocalFolder[LrcFolder] ||
                  m_FolderList[Index].first == LocalFolder[SongFolder] );
     else
          return false;
}

bool LrcSearchSetting::GetLrcDownloadUrl(unsigned int LrcIdx, tstring & LrcUrl)
{
     if( m_SearchEngineAPI[m_SearchEngineIdx].GetLrcDownloadUrl(LrcIdx, LrcUrl) ) 
         return true;

     return false;
}